package com.qf.set.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.qf.common.constant.UserConstants;
import com.qf.common.core.domain.TreeSelect;
import com.qf.common.utils.SecurityUtils;
import com.qf.common.utils.StringUtils;
import com.qf.set.domain.TmsDepartment;
import com.qf.set.mapper.TmsDepartmentMapper;
import com.qf.set.service.ITmsDepartmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class TmsDepartmentServiceImpl implements ITmsDepartmentService {

    @Autowired
    private TmsDepartmentMapper deptMapper;

    /**
     * 查询部门列表
     */
    @Override
    public List<TmsDepartment> selectDeptList(TmsDepartment dept) {
        return deptMapper.selectDeptList(dept);
    }

    /**
     * 构建部门树形选择结构（使用Hutool）
     */
    @Override
    public List<TreeSelect> selectDeptTreeSelect() {
        List<TmsDepartment> deptList = deptMapper.selectDeptList(new TmsDepartment());
        if (CollUtil.isEmpty(deptList)) {
            return new ArrayList<>();
        }

        // Hutool树形配置
        TreeNodeConfig config = new TreeNodeConfig();
        config.setIdKey("id");
        config.setParentIdKey("parentId");
        config.setNameKey("deptName");
        // config.setRootId(0L); // 顶级部门父ID设为0

        // 构建Hutool树形结构
        List<Tree<Long>> hutoolTrees = TreeUtil.build(deptList, 0L, config, (dept, tree) -> {
            tree.setId(dept.getId());
            tree.setParentId(dept.getParentId() == null ? 0L : dept.getParentId());
            tree.setName(dept.getDeptName());
            // 扩展字段：部门状态（用于禁用节点）
            tree.putExtra("disabled", "禁用".equals(dept.getDeptStatus()));
        });

        // 转换为项目TreeSelect格式
        return hutoolTrees.stream().map(this::convertToTreeSelect).collect(Collectors.toList());
    }

    /**
     * Hutool Tree转换为项目TreeSelect
     */
    private TreeSelect convertToTreeSelect(Tree<Long> hutoolTree) {
        TreeSelect treeSelect = new TreeSelect();
        treeSelect.setId(hutoolTree.getId());
        treeSelect.setLabel((String) hutoolTree.getName());
        treeSelect.setDisabled(Convert.toBool(hutoolTree.get("disabled"), false));

        // 递归处理子节点
        if (CollUtil.isNotEmpty(hutoolTree.getChildren())) {
            treeSelect.setChildren(
                    hutoolTree.getChildren().stream()
                            .map(this::convertToTreeSelect)
                            .collect(Collectors.toList())
            );
        }
        return treeSelect;
    }

    /**
     * 通过ID查询部门
     */
    @Override
    public TmsDepartment selectDeptById(Long id) {
        return deptMapper.selectDeptById(id);
    }

    /**
     * 校验部门名称是否唯一
     */
    @Override
    public boolean checkDeptNameUnique(TmsDepartment dept) {
        Long deptId = StringUtils.isNull(dept.getId()) ? -1L : dept.getId();
        TmsDepartment info = deptMapper.checkDeptNameUnique(dept.getDeptName(), dept.getParentId());

        // 如果存在同名部门且不是当前部门，则不唯一
        if (StringUtils.isNotNull(info) && !info.getId().equals(deptId)) {
            return UserConstants.NOT_UNIQUE;
        }
        // 否则唯一
        return UserConstants.UNIQUE;
    }

    /**
     * 新增部门
     */
    @Override
    @Transactional
    public int insertDept(TmsDepartment dept) {
        TmsDepartment parent = deptMapper.selectDeptById(dept.getParentId());
        // 父部门不存在或为顶级部门
        if (parent == null) {
            dept.setParentId(0L);
        }

        // 设置创建信息
        dept.setCreator(SecurityUtils.getUsername());
        dept.setCreateTime(new Date());
        return deptMapper.insertDept(dept);
    }

    /**
     * 修改部门
     */
    @Override
    @Transactional
    public int updateDept(TmsDepartment dept) {
        // 移除部门存在性检查，由控制器确保部门存在
        // 通过更新影响行数判断是否成功

        // 不能选择自身作为父部门
        if (dept.getId().equals(dept.getParentId())) {
            throw new RuntimeException("上级部门不能是自身");
        }

        // 检查父部门是否存在
        if (dept.getParentId() != 0) {
            TmsDepartment parent = deptMapper.selectDeptById(dept.getParentId());
            if (parent == null) {
                throw new RuntimeException("上级部门不存在");
            }
        }

        // 设置更新信息
        dept.setUpdateBy(SecurityUtils.getUsername());
        dept.setUpdateTime(new Date());
        return deptMapper.updateDept(dept);
    }

    /**
     * 删除部门
     */
    @Override
    @Transactional
    public int deleteDeptById(Long id) {
        // 检查是否有子部门
        if (hasChildByDeptId(id)) {
            throw new RuntimeException("存在子部门，无法删除");
        }

        // 检查是否关联用户
        if (checkDeptExistUser(id)) {
            throw new RuntimeException("部门下存在用户，无法删除");
        }

        return deptMapper.deleteDeptById(id);
    }

    /**
     * 检查部门是否有子部门
     */
    @Override
    public boolean hasChildByDeptId(Long id) {
        int count = deptMapper.hasChildByDeptId(id);
        return count > 0;
    }

    /**
     * 检查部门是否关联用户
     */
    @Override
    public boolean checkDeptExistUser(Long id) {
        int count = deptMapper.checkDeptExistUser(id);
        return count > 0;
    }
}
